import 'dart:math';

import 'package:flutter/material.dart';
import 'package:x3_charts_core/x3_charts_core.dart';

///**
///* @author hrongyong
///* @date   3/2/21
///* @email hrongyong@gmail.com
///* Description: 多区域环形图
///*/

class MultiAreaRingChartPainter extends CustomPainter {
  final List<GeneralChartModel> chartList;
  final Color backgroundColor;

  ///动画数值
  final Animation<double> repaint;

  MultiAreaRingChartPainter({
    @required this.chartList,
    @required this.repaint,
    this.backgroundColor = Colors.white,
    this.displayPercentageToCircle = false,
    this.showTickMark = true,
  }) : super(repaint: repaint);

  ///最大半径
  double maxRadius = 0.0;

  Paint _paint = Paint()..style = PaintingStyle.stroke;

  ///圆的度数
  final double CIRCLE_ANGLE = 360;

  ///刻度的长度
  final double scaleLength = 10;

  ///文字
  final TextPainter _textPainter = TextPainter(textDirection: TextDirection.ltr);

  ///文字
  final TextPainter _painter01 = TextPainter(textDirection: TextDirection.ltr);
  final TextPainter _painter02 = TextPainter(textDirection: TextDirection.ltr);
  final TextPainter _painter03 = TextPainter(textDirection: TextDirection.ltr);

  ///默认圆环颜色
  final Color defaultRingColor = Colors.lightBlueAccent;

  ///圆环上是否显示占比
  final bool displayPercentageToCircle;

  ///是否显示圆环和文字之间的刻度线
  final bool showTickMark;

  @override
  void paint(Canvas canvas, Size size) {
    if (chartList == null || chartList.length == 0) return;

    ///确定最大半径
    maxRadius = min(size.width / 2, size.height / 2) * 0.6;
    _paint..strokeWidth = maxRadius / 3;

    ///绘制背景
    canvas.drawRect(Offset.zero & size, Paint()..color = backgroundColor);

    ///移动绘画中心
    canvas.translate(size.width / 2, size.height / 2);

    ///绘制圆环
    _drawACircle(canvas, size);

    ///绘制圆环上的延伸刻度线和文本
    drawTickMarksAndText(canvas, size);
  }

  drawTickMarksAndText(Canvas canvas, Size size) {
    canvas.save();

    ///累计的弧度
    double grandTotal = 0.0;

    for (int i = 0; i < chartList.length; i++) {
      if (i != 0) {
        grandTotal += CIRCLE_ANGLE * chartList[i - 1].firstHistogram;
      }

      ///圆环每段的中心
      double x0 = (maxRadius) * sin(ChartTools.degToRad(grandTotal + (CIRCLE_ANGLE * chartList[i].firstHistogram) / 2));
      double y0 = -(maxRadius) * cos(ChartTools.degToRad(grandTotal + (CIRCLE_ANGLE * chartList[i].firstHistogram) / 2));

      ///绘制圆弧占比
      if (displayPercentageToCircle) _drawArcProportion(canvas, size, Offset(x0, y0), "${(chartList[i].firstHistogram * 100).toInt()}%");

      double x1 = (maxRadius + _paint.strokeWidth / 2 + 2) * sin(ChartTools.degToRad(grandTotal + (CIRCLE_ANGLE * chartList[i].firstHistogram) / 2));
      double y1 = -(maxRadius + _paint.strokeWidth / 2 + 2) * cos(ChartTools.degToRad(grandTotal + (CIRCLE_ANGLE * chartList[i].firstHistogram) / 2));
      double x2 = (maxRadius + _paint.strokeWidth / 2 + scaleLength) * sin(ChartTools.degToRad(grandTotal + (CIRCLE_ANGLE * chartList[i].firstHistogram) / 2));
      double y2 = -(maxRadius + _paint.strokeWidth / 2 + scaleLength) * cos(ChartTools.degToRad(grandTotal + (CIRCLE_ANGLE * chartList[i].firstHistogram) / 2));

      ///绘制刻度线
      if (showTickMark)
        canvas.drawLine(
            Offset(x1, y1),
            Offset(x2, y2),
            Paint()
              ..color = chartList[i].firstHistogramColor == null ? defaultRingColor : chartList[i].firstHistogramColor
              ..strokeWidth = 2);

      ///绘制文字
      _drawAxisText(
        canvas,
        size,
        first: chartList[i].firstHistogramDescription,
        second: chartList[i].secondHistogramDescription,
        third: chartList[i].thirdHistogramDescription,
        offset: Offset(x2, y2),
      );
    }

    canvas.restore();
  }

  void _drawArcProportion(Canvas canvas, Size size, Offset offset, String title) {
    TextSpan text = TextSpan(text: title, style: TextStyle(fontSize: 10, color: Colors.black));
    _textPainter.text = text;
    _textPainter.layout(); // 进行布局
    Size textSize = _textPainter.size;
    Offset textOffsetPos = Offset(offset.dx - textSize.width / 2, offset.dy - textSize.height / 2);
    _textPainter.paint(canvas, textOffsetPos);
  }

  void _drawAxisText(Canvas canvas, Size size, {String first, String second, String third, Offset offset}) {
    ///绘制标题
    TextSpan text01 = TextSpan(text: first, style: TextStyle(fontSize: 10, color: Colors.black));
    TextSpan text02 = TextSpan(text: second, style: TextStyle(fontSize: 10, color: Colors.black));
    TextSpan text03 = TextSpan(text: third, style: TextStyle(fontSize: 10, color: Colors.black));

    _painter01.text = text01;
    _painter02.text = text02;
    _painter03.text = text03;
    _painter01.layout(); // 进行布局
    _painter02.layout(); // 进行布局
    _painter03.layout(); // 进行布局
    Size firstSize = _painter01.size;
    Size secondSize = _painter02.size;
    Size thirdSize = _painter03.size;
    Size air = Size(0, 0);
    if (firstSize.width == 0.0) firstSize = air;
    if (secondSize.width == 0.0) secondSize = air;
    if (thirdSize.width == 0.0) thirdSize = air;

    List<Offset> textOffsetPos = ChartTools.roundStructureThreeHeadingsOffset(offset: offset, firstSize: firstSize, secondSize: secondSize, thirdSize: thirdSize);
    _painter01.paint(canvas, textOffsetPos[0]);
    _painter02.paint(canvas, textOffsetPos[1]);
    _painter03.paint(canvas, textOffsetPos[2]);
  }

  _drawACircle(Canvas canvas, Size size) {
    canvas.save();
    Rect rect = Rect.fromCenter(center: Offset.zero, width: maxRadius * 2, height: maxRadius * 2);
    canvas.rotate(-pi / 2);
    double startAngle = 0.0;
    chartList.forEach((element) {
      canvas.drawArc(rect, startAngle * repaint.value, (2 * pi) * element.firstHistogram * repaint.value, false, _paint..color = element.firstHistogramColor == null ? defaultRingColor : element.firstHistogramColor);

      startAngle += (2 * pi) * element.firstHistogram;
    });
    canvas.restore();
  }

  @override
  bool shouldRepaint(covariant MultiAreaRingChartPainter oldDelegate) => oldDelegate.chartList != chartList;
}
